﻿#include "FITKAbaqusAdaptorMaterial.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"
#include "FITKAbaqusAdaptorMaterialDensity.h"
#include "FITKAbaqusAdaptorMaterialElastic.h"
#include "FITKAbaqusAdaptorMaterialPlastic.h"
#include "FITKAbaqusAdaptorMaterialHyperelastic.h"
#include "FITKAbaqusAdaptorMaterialDamageInitiation.h"
#include "FITKAbaqusAdaptorMaterialExpansion.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterial.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialDensity.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialElastic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialPlastic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialHyperElastic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialDamping.h"

namespace IO
{
    QString FITKAbaqusAdaptorMaterial::getAdaptorClass()
    {
        //返回数据类名 带命名空间
        return "IO::FITKAbaqusAdaptorMaterial";
    }

    bool FITKAbaqusAdaptorMaterial::adaptR()
    {
        _materialData = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if (!_materialData || !_reader) return false;

        //回退一行 处理关键字信息
        _reader->backLine();

        QString line = _reader->readLine();
        if (!line.toLower().startsWith("*material")) return false;
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString matName = s["name"];
        _materialData->setDataObjectName(matName);

        bool readOK = false;
        while (!_reader->atEnd())
        {
            line = _reader->readLine();
            if (!line.startsWith("*")) continue;
            s.reset(line);
            QString sH = s.getHeader().toLower();

            if (sH == "density")
            {
                readOK = this->readDensity();
            }
            else if (sH == "elastic")
            {
                readOK = this->readElastic();
            }
            else if (sH == "plastic")
            {
                readOK = this->readPlastic();

            }
            else if (sH == "hyperelastic" || sH == "anisotropic hyperelastic")
            {
                readOK = this->readHyperelastic();
            }
            else if (sH == "damage initiation")
            {
                readOK = this->readDamageInitiation();
            }
            else if (sH == "damping")
            {
                readOK = this->readDamping();
            }
            else if (sH == "expansion")
            {
                readOK = this->readExpansion();
            }
            else if (sH == "material") //作为材料读取跳出条件
            {
                return true;
            }
            //此字段没有结束符 暂时以**号作为结束，有可能产生逃逸的风险
            else
            {
                return true;
                ////不支持的关键字
                //readOK = false;
                //_reader->consoleMessage(3, "Read Material Error Key : " + sH);
            }

            if (readOK && !_reader->atEnd())
            {
                _reader->backLine();
            }
            else
            {
                continue;
            }

        }
        if (_reader->atEnd())return true;
        return false;
    }

    bool FITKAbaqusAdaptorMaterial::adaptW()
    {
        //通过工厂创建
        _materialData = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if (!_materialData || !_writer) return false;

        bool isW = true;
        // 写出函数主体
        QTextStream* stream = _writer->getStream();
        QString materialName = _materialData->getDataObjectName();
        materialName = materialName.contains(' ') ? QString("\"%1\"").arg(materialName) : materialName;
        *stream << "*Material, name=" << materialName << endl;
        isW &= writeDamageInitiation();
        isW &= writeDamping();
        isW &= writeDensity();
        isW &= writeElastic();
        isW &= writeExpansion();
        isW &= writeHyperelastic();
        isW &= writePlastic();
        return isW;
    }

    bool FITKAbaqusAdaptorMaterial::readDensity()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialDensity>("INP", "Interface::FITKAbaMaterialDensity");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptR();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::writeDensity()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialDensity>("INP", "Interface::FITKAbaMaterialDensity");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptW();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::readElastic()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialElastic>("INP", "Interface::FITKAbaMaterialElastic");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptR();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::writeElastic()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialElastic>("INP", "Interface::FITKAbaMaterialElastic");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptW();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::readPlastic()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialPlastic>("INP", "Interface::FITKAbaMaterialPlastic");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptR();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::writePlastic()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialPlastic>("INP", "Interface::FITKAbaMaterialPlastic");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptW();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::readJohnsonCookDamage()
    {
        return false;
    }

    bool FITKAbaqusAdaptorMaterial::readHyperelastic()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialHyperelastic>("INP", "Interface::FITKAbaMaterialHyperElastic");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptR();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::writeHyperelastic()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialHyperelastic>("INP", "Interface::FITKAbaMaterialHyperElastic");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptW();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::readDamageInitiation()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialDamageInitiation>("INP", "Interface::FITKAbaMaterialJohnsonCookDamage");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptR();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::writeDamageInitiation()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialDamageInitiation>("INP", "Interface::FITKAbaMaterialJohnsonCookDamage");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptW();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::readDamping()
    {
        //回退一行 处理关键字信息 校验
        _reader->backLine();
        QString line = _reader->readLine();
        if (!line.toLower().startsWith("*damping")) return false;
        InpKeyLineSpliter s(line, _reader);
        //获取全部数据
        bool ok = false;
        //Alpha
        double alpha = s["alpha"].toDouble(&ok);
        if (!ok)return false;
        //Beta
        double beta = s["beta"].toDouble(&ok);
        if (!ok)return false;
        //复合
        double composite = s["composite"].toDouble(&ok);
        if (!ok)return false;
        //结构
        double structural = s["structural"].toDouble(&ok);
        if (!ok)return false;
        //创建阻尼
        bool create = _materialData->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Damping);
        if (!create)return false;
        //获取数据
        Interface::FITKAbaMaterialDamping* damping = dynamic_cast<Interface::FITKAbaMaterialDamping *>
            (_materialData->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Damping));
        damping->setAlpha(alpha);
        damping->setBeta(beta);
        damping->setComposite(composite);
        damping->setStructural(structural);
        //读取下一行
        _reader->readLine();
        return true;
    }

    bool FITKAbaqusAdaptorMaterial::writeDamping()
    {
        if (!_materialData || !_writer) return false;
        //获取数据
        Interface::FITKAbaMaterialDamping* damping = dynamic_cast<Interface::FITKAbaMaterialDamping *>
            (_materialData->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Damping));
        if (!damping)return true;
        QTextStream* stream = _writer->getStream();
        //Alpha
        double alpha = damping->getAlpha();
        //Beta
        double beta = damping->getBeta();
        //复合
        double composite = damping->getComposite();
        //结构
        double structural = damping->getStructural();
        //写出数据
        QString lineOne = QString("*Damping, alpha=%1, beta=%2, composite=%3, structural=%4").arg(_writer->double2String(alpha, 8, 0))
            .arg(_writer->double2String(beta, 8, 0)).arg(_writer->double2String(composite, 8, 0)).arg(_writer->double2String(structural, 8, 0));
        *stream << lineOne << endl;
        return true;
    }

    bool FITKAbaqusAdaptorMaterial::readExpansion()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialExpansion>("INP", "Interface::FITKAbaMaterialExpansion");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptR();

        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorMaterial::writeExpansion()
    {
        //通过工厂创建
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorMaterialExpansion>("INP", "Interface::FITKAbaMaterialExpansion");
        if (adaptor == nullptr)
        {
            return false;
        }
        //设置写出器
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(_materialData);
        bool ok = adaptor->adaptW();

        delete adaptor;
        return ok;
    }
}
